package events;

import com.sun.org.apache.xpath.internal.operations.Bool;

import java.util.ArrayList;
import java.util.HashMap;

public class EventEmitter {

    private HashMap<String, ArrayList<EventHandler>> handlers;

    public EventEmitter() {
        this.handlers = new HashMap<String, ArrayList<EventHandler>>();
    }

    public ArrayList<EventHandler> listeners(String type) {
        ArrayList<EventHandler> handlers = new ArrayList<EventHandler>();
        ArrayList<EventHandler> originalHandlers;

        originalHandlers = this.handlers.containsKey(type) ? this.handlers.get(type) : new ArrayList<EventHandler>();

        for (EventHandler handler : originalHandlers) {
            handlers.add(handler);
        }
        return handlers;
    }

    public EventEmitter on(String type, EventHandler handler) {
        ArrayList<EventHandler> handlers = this.listeners(type);

        if (0 == handlers.size()) {
            handlers.add(handler);
            this.handlers.put(type, handlers);
        }
        else {
            this.handlers.get(type).add(handler);
        }

        return this;
    }

    public EventEmitter emit(String type, Event event) {
        ArrayList<EventHandler> handlers = this.listeners(type);

        event.setTarget(this);
        for (EventHandler handler : handlers) {
            handler.action(event);
        }

        return this;
    }


    private Boolean has(String type, EventHandler handler) {
        Boolean ret = false;
        ArrayList<EventHandler> handlers = this.listeners(type);

        if (0 != handlers.size()) {

            for (EventHandler aHandler : handlers) {
                if (aHandler.equals(handler)) {
                    ret = true;
                }
            }

        }

        return ret;
    }

    private EventEmitter removeHandler(String type, EventHandler handler) {
        ArrayList<EventHandler> handlers = this.listeners(type);
        int where = -1;
        for (int i = 0, len = handlers.size(); i < len; i++) {
            if (handlers.get(i).equals(handler)) {
                where = i;
            }
        }
        this.handlers.get(type).remove(where);
        return this;
    }

    public EventEmitter off(String type, EventHandler handler) {
        return this.has(type, handler) ?
               this.removeHandler(type, handler) :
               this;
    }
}
